
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "Address.hpp"
#include "impl/InterfaceImpl.hpp"

namespace huluwa {
namespace net {

/** 
 * @brief  Network Interface.
 *
 * Network Interface class uses bridge pattern.
 */
class Interface {

public:
    static Interface *GetIntfByName(const char *name)
    {
        if (!initialized_) {
            impl::InterfaceImpl::DumpInterface(Interface::FillIntfPool);
            initialized_ = true;
        }

        std::vector<Interface *>::iterator i;

        for (i = pool_.begin(); i != pool_.end(); ++i) {
            if ((*i)->GetName() == name)
                return *i;
        }

        return 0;
    }

    bool IsEthernet() const
    {
        return impl_->IsEthernet();
    }

    bool IsLoopback() const
    {
        return impl_->IsLoopback();
    }

    std::string GetName() const
    {
        return impl_->GetName();
    }

    std::size_t GetMTU() const 
    {
        return impl_->GetMTU();
    }

    Address GetLinkAddress() const
    {
        return impl_->GetLinkAddress();
    }

    Address GetAddress() const
    {
        return impl_->GetAddress();
    }

private:
    Interface(const impl::InterfaceImpl* impl) 
        : impl_(impl)
    {
    }
    
    ~Interface() 
    {
        delete impl_;
    }

    static void FillIntfPool(const impl::InterfaceImpl *impl)
    {
        pool_.push_back(new Interface(impl));
    }

    static bool initialized_;
    static std::vector<Interface *> pool_;
    const impl::InterfaceImpl *impl_;
};

} // namespace net
} // namespace huluwa
